#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <ctype.h>

#define NONE -1
#define IN_REDIR 0
#define OUT_REDIR 1
#define APPEND_REDIR 2

char envname[1024];
int exitcode;
char* filename;
int redirectstatus;

int main()
{
   while(1)
   {
      filename=NULL;
      redirectstatus=NONE;

      char cwdname[1024];
      getcwd(cwdname,1024);
      printf("[%s@%s %s]$ ",getenv("LOGNAME"),getenv("HOSTNAME"),cwdname);  

      char commandname[1024];
      fgets(commandname,1024,stdin);
      
      commandname[strlen(commandname)-1]='\0';
      
      char* pos=commandname;

      while(*pos!='\0')
      {
         if(*pos=='>')
         {
            if(*(pos+1)=='>')
            {
               redirectstatus=APPEND_REDIR;
               *pos='\0';
               pos+=2;
               while(isspace(*pos)) ++pos;
               filename=pos;
               break;
            }
            else
            {
               redirectstatus=OUT_REDIR;
               *pos='\0';
               ++pos;
               while(isspace(*pos)) ++pos;
               filename=pos;
               break;
            }
         }
         else if(*pos=='<')
         {
            redirectstatus=IN_REDIR;
            *pos='\0';
            ++pos;
            while(isspace(*pos)) ++pos;
            filename=pos;
            break;
         }

         ++pos;
      }

      char* argv[1024]={NULL};
      int i=0;
      for(argv[i++]=strtok(commandname," ");argv[i]=strtok(NULL," ");)
      {
         i++;
      }
      int argc=i;

      
      if(argc==2 && strcmp(argv[0],"cd")==0)
      {
         chdir(argv[1]);
         char CWDname[1024];
         getcwd(CWDname,1024);
         char pwdname[1024];
         sprintf(pwdname,"PWD=%s",CWDname);
         putenv(pwdname);
         continue;
      }
      else if(argc==2 && strcmp(argv[0],"export")==0)
      {
         strcpy(envname,argv[1]);
         putenv(envname);
         //putenv(argv[1]);
         continue;
      }
      else if(argc==2 && strcmp(argv[0],"echo")==0)
      {
         if(*argv[1]=='$')
         {
            printf("退出码:%d\n",exitcode);
            exitcode=0;
         }
         else
         {
            printf("%s\n",argv[1]);
         }
         continue;
      }

      if(strcmp(argv[0],"ls")==0)
      {
         argv[argc++]="--color";
         argv[argc]=NULL;
      }

      pid_t id=fork();
      if(id==0)
      {
         if(redirectstatus==APPEND_REDIR)
         {
            int fd=open(filename,O_CREAT|O_WRONLY|O_APPEND,0666);
            dup2(fd,1);
         }
         else if(redirectstatus==OUT_REDIR)
         {
            int fd=open(filename,O_CREAT|O_WRONLY|O_TRUNC,0666);
            dup2(fd,1);
         }
         else if(redirectstatus==IN_REDIR)
         {
            int fd=open(filename,O_RDONLY,0666);
            dup2(fd,0);
         }

         execvp(argv[0],argv);
         exit(11);
      }
      else
      {
         int status=0;
         waitpid(id,&status,0);
         if(WIFEXITED(status))
         {
            printf("退出码:%d\n",WEXITSTATUS(status));
            exitcode=WEXITSTATUS(status);
         }
         else
         {
            printf("退出异常");
         }
      }
   }    

   return 0;
}
